#include "CharacterFactory.h"
#include <fstream>
#include "Character\NonPlayerCharacter.h"
#include "Character\PlayerCharacter.h"
#include "Character\MagicObject.h"
#include "../SpellFactory.h"
#include <string>
using namespace std;

// Loads a player character from file and returns a new object
PlayerCharacter* CharacterFactory::makeCharacter(std::string iFileName)
{
	string prefName = "Name:";
	string prefDesc = "Desc:";
	string prefStrength = "Strength:";
	string prefCraft = "Craft:";
	string prefLife = "Life:";
	string prefGold = "Gold:";
	string prefFate = "Fate:";
	string prefImage = "Image:";
	string prefObject = "Object:";
	string prefStrenVal = "StrenVal:";
	string prefFollower = "Follower:";
	string prefSpell = "Spell:";
	string image="";
	string name="";
	string desc="";
	int stren=0;
	int craft=0;
	int gold=0;
	int fate=0;
	int life=0;
	int strenVal=0;
	vector <MagicObject*> objects;
	vector <NonPlayerCharacter *> followers;
	vector <ISpell *> spells;

	string line;
	ifstream myfile (iFileName);
	if (myfile.is_open())
	{
		while ( myfile.good() )
		{
			getline (myfile,line);
			if(pref(line, prefName))
				name = line.substr(prefName.size());
			else if (pref(line, prefDesc))
				desc = line.substr(prefDesc.size());
			else if(pref(line, prefStrength))
				stren = atoi(line.substr(prefStrength.size()).c_str());
			else if(pref(line, prefStrenVal))
				strenVal = atoi(line.substr(prefStrenVal.size()).c_str());
			else if (pref(line, prefCraft))
				craft = atoi(line.substr(prefCraft.size()).c_str());
			else if (pref(line, prefGold))
				gold = atoi(line.substr(prefGold.size()).c_str());
			else if (pref(line, prefFate))
				fate = atoi(line.substr(prefFate.size()).c_str());
			else if (pref(line, prefLife))
				life = atoi(line.substr(prefLife.size()).c_str());
			else if (pref(line, prefImage))
				image = line.substr(prefImage.size()).c_str();
			else if (pref(line, prefObject))
				objects.push_back(makeMagicObject(line.substr(prefObject.size())));
			else if (pref(line, prefFollower))
				followers.push_back(makeFollower(line.substr(prefFollower.size())));
			else if (pref(line, prefSpell))
			{	
				string spell = line.substr(prefSpell.size()).c_str();
				ISpell * spellInst = SpellFactory::spellFromString(spell);
				spells.push_back(spellInst);
			}
			else
				throw "Couldn't load the character - the file has an incorrect fromat.";
		}
		myfile.close();
	}
	else 
	{
		throw "Couldn't load the character - the file doesn't exist or can't be read.";
	}

	PlayerCharacter *p = new PlayerCharacter(name,desc,strenVal,0);
	p->setGoldenCoinNumberInPossession(gold);
	p->setFateTokenNumberInPossession(fate);
	p->setLifeCounter(life);
	p->setStrengthCounter(stren);
	p->setCraftCounter(craft);

	for (int i = 0; i < spells.size(); ++i)
		p->addSpell(spells.at(i));

	for(int i = 0; i < objects.size(); ++i)
		p->addMagicObject(objects[i]);

	for(int i = 0; i < followers.size(); ++i)
		p->addFollower(followers[i]);

	p->setPicture(image.c_str());

	return p;
}

// Loads a non-player character from file and returns a new object
NonPlayerCharacter* CharacterFactory::makeFollower(string iFileName)
{
	string prefName = "Name:";
	string prefDesc = "Desc:";
	string prefStrength = "Strength:";
	string prefCraft = "Craft:";
	string prefLife = "Life:";
	string prefGold = "Gold:";
	string prefFate = "Fate:";
	string prefImage = "Image:";
	string prefObject = "Object:";
	string image="";
	string name="";
	string desc="";
	int stren=0;
	int craft=0;
	int gold=0;
	int fate=0;
	int life=0;

	string line;
	ifstream myfile (iFileName);
	if (myfile.is_open())
	{
		while ( myfile.good() )
		{
			getline (myfile,line);
			if(pref(line, prefName))
				name = line.substr(prefName.size());
			else if (pref(line, prefDesc))
				desc = line.substr(prefDesc.size());
			else if(pref(line, prefStrength))
				stren = atoi(line.substr(prefStrength.size()).c_str());
			else if (pref(line, prefCraft))
				craft = atoi(line.substr(prefCraft.size()).c_str());
			else if (pref(line, prefGold))
				gold = atoi(line.substr(prefGold.size()).c_str());
			else if (pref(line, prefFate))
				fate = atoi(line.substr(prefFate.size()).c_str());
			else if (pref(line, prefLife))
				life = atoi(line.substr(prefLife.size()).c_str());
			else if (pref(line, prefImage))
				image = line.substr(prefImage.size()).c_str();
			else
				throw "Couldn't load the follower - the file has an incorrect format.";
		}
		myfile.close();
	}
	else 
		throw "Couldn't load the follower - the file doesn't exist or can't be read."; 

	NonPlayerCharacter *p = new NonPlayerCharacter(name,desc,stren,craft);
	p->setPicture(image.c_str());

	return p;
}

// Loads a magic object from file and returns a new object
MagicObject* CharacterFactory::makeMagicObject(std::string iFileName)
{
	string prefName = "Name:";
	string prefDesc = "Desc:";
	string prefStrength = "Strength:";
	string prefCraft = "Craft:";
	string prefLife = "Life:";
	string prefGold = "Gold:";
	string prefFate = "Fate:";
	string prefImage = "Image:";
	string image="";
	string name="";
	string desc="";
	int stren=0;
	int craft=0;
	int gold=0;
	int fate=0;
	int life=0;

	string line;
	ifstream myfile (iFileName);
	if (myfile.is_open())
	{
		while ( myfile.good() )
		{
			getline (myfile,line);
			if(pref(line, prefName))
				name = line.substr(prefName.size());
			else if (pref(line, prefDesc))
				desc = line.substr(prefDesc.size());
			else if(pref(line, prefStrength))
				stren = atoi(line.substr(prefStrength.size()).c_str());
			else if (pref(line, prefCraft))
				craft = atoi(line.substr(prefCraft.size()).c_str());
			else if (pref(line, prefGold))
				gold = atoi(line.substr(prefGold.size()).c_str());
			else if (pref(line, prefFate))
				fate = atoi(line.substr(prefFate.size()).c_str());
			else if (pref(line, prefLife))
				life = atoi(line.substr(prefLife.size()).c_str());
			else if (pref(line, prefImage))
				image = line.substr(prefImage.size()).c_str();
			else
				throw "Couldn't load the magic object - the file has an incorrect format.";
		}
		myfile.close();
	}
	else 
		throw "Couldn't load the magic object - the file doesn't exist or can't be read."; 

	MagicObject *m = new MagicObject(name,stren,craft);

	m->setPicture(image.c_str());

	return m;
}

// Tells whether or not str starts with pref
bool CharacterFactory::pref(string str, string pref)
{
	return (str.compare(0, pref.size(), pref) == 0);
}